package com.loe.test

import android.os.Handler
import android.os.Looper
import okhttp3.*
import okio.ByteString
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager

/**
 * WebSocket 连接管理工具类
 */
class WebSocketManager(private val url: String)
{
    /** 心跳间隔(秒)，默认30秒 */
    private val heartInterval: Long = 10

    /** 重连间隔(毫秒)，默认5秒 */
    private val reconnectInterval: Long = 5000

    private var messageListener: MessageListener? = null

    // WebSocket 实例
    private var webSocket: WebSocket? = null

    // OkHttp 客户端
    private val client by lazy()
    {
        // 创建信任所有证书的 TrustManager
        val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager
        {
            override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String)
            {
            }

            override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String)
            {
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf()
        })

        // 创建 SSLContext 并使用自定义 TrustManager
        val sslContext = SSLContext.getInstance("SSL").apply()
        {
            init(null, trustAllCerts, java.security.SecureRandom())
        }

        // 创建 OkHttpClient 并应用自定义 SSL Socket Factory
        OkHttpClient.Builder()
            .sslSocketFactory(sslContext.socketFactory, trustAllCerts[0] as X509TrustManager)
            .hostnameVerifier { _, _ -> true } // 跳过主机名验证
            .build()
    }

    // 重连相关
    private var reconnectAttempts = 0
    private val isReconnecting = AtomicBoolean(false)
    private val handler = Handler(Looper.getMainLooper())

    // 心跳相关
    private var heartbeatJob: Runnable? = null
    private val isConnected = AtomicBoolean(false)

    // 消息队列（当连接断开时缓存消息）
    private val messageQueue = mutableListOf<Any>()
    private val isQueueProcessing = AtomicBoolean(false)

    /**
     * 连接 WebSocket
     */
    fun connect()
    {
        if (isConnected.get()) return

        val request = Request.Builder()
            .url(url)
            .build()

        webSocket = client.newWebSocket(request, object : WebSocketListener()
        {
            override fun onOpen(webSocket: WebSocket, response: Response)
            {
                super.onOpen(webSocket, response)
                isConnected.set(true)
                reconnectAttempts = 0
                messageListener?.onConnected()
                startHeartbeat()
                processMessageQueue()
            }

            override fun onMessage(webSocket: WebSocket, text: String)
            {
                super.onMessage(webSocket, text)
                messageListener?.onMessage(text)
            }

            override fun onMessage(webSocket: WebSocket, bytes: ByteString)
            {
                super.onMessage(webSocket, bytes)
                messageListener?.onMessage(bytes)
            }

            override fun onClosing(webSocket: WebSocket, code: Int, reason: String)
            {
                super.onClosing(webSocket, code, reason)
                messageListener?.onDisconnecting(code, reason)
            }

            override fun onClosed(webSocket: WebSocket, code: Int, reason: String)
            {
                super.onClosed(webSocket, code, reason)
                isConnected.set(false)
                stopHeartbeat()
                messageListener?.onDisconnected(code, reason)
            }

            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?)
            {
                super.onFailure(webSocket, t, response)
                isConnected.set(false)
                stopHeartbeat()
                messageListener?.onConnectionFailed(t)
                attemptReconnect()
            }
        })
    }

    fun setOnMessageListener(listener: MessageListener)
    {
        messageListener = listener
    }

    /**
     * 断开 WebSocket 连接
     */
    fun disconnect()
    {
        stopHeartbeat()
        handler.removeCallbacksAndMessages(null)
        webSocket?.close(1000, "Normal closure")
        webSocket = null
        isConnected.set(false)
    }

    /**
     * 发送文本消息
     * @param message 文本消息
     */
    fun sendMessage(message: String)
    {
        when
        {
            isConnected.get() -> webSocket?.send(message)
            else ->
            {
                synchronized(messageQueue) {
                    messageQueue.add(message)
                }
                if (!isConnected.get() && !isReconnecting.get())
                {
                    connect()
                }
            }
        }
    }

    /**
     * 发送二进制消息
     * @param data 二进制数据
     */
    fun sendBinary(data: ByteString)
    {
        when
        {
            isConnected.get() -> webSocket?.send(data)
            else ->
            {
                synchronized(messageQueue)
                {
                    messageQueue.add(data)
                }
                if (!isConnected.get() && !isReconnecting.get())
                {
                    connect()
                }
            }
        }
    }

    /**
     * 开始心跳
     */
    private fun startHeartbeat()
    {
        heartbeatJob?.let { handler.removeCallbacks(it) }

        heartbeatJob = object : Runnable
        {
            override fun run()
            {
                if (isConnected.get())
                {
                    webSocket?.send("") // 发送心跳包
                    handler.postDelayed(this, heartInterval * 1000)
                }
            }
        }

        handler.postDelayed(heartbeatJob!!, heartInterval * 1000)
    }

    /**
     * 停止心跳
     */
    private fun stopHeartbeat()
    {
        heartbeatJob?.let {
            handler.removeCallbacks(it)
            heartbeatJob = null
        }
    }

    /**
     * 尝试重连
     */
    private fun attemptReconnect()
    {
        if (isReconnecting.get())
        {
            return
        }

        isReconnecting.set(true)
        reconnectAttempts++

        handler.postDelayed({
            if (!isConnected.get())
            {
                messageListener?.onReconnecting(reconnectAttempts)
                connect()
            }
            isReconnecting.set(false)
        }, reconnectInterval)
    }

    /**
     * 处理消息队列
     */
    private fun processMessageQueue()
    {
        if (isQueueProcessing.get() || messageQueue.isEmpty()) return

        isQueueProcessing.set(true)
        synchronized(messageQueue) {
            val iterator = messageQueue.iterator()
            while (iterator.hasNext())
            {
                when (val message = iterator.next())
                {
                    is String -> webSocket?.send(message)
                    is ByteString -> webSocket?.send(message)
                }
                iterator.remove()
            }
        }
        isQueueProcessing.set(false)
    }
}

/**
 * 消息监听接口
 */
interface MessageListener
{
    // 连接成功
    fun onConnected()
    {
    }

    // 收到消息
    fun onMessage(message: String)

    // 收到二进制消息
    fun onMessage(bytes: ByteString)
    {
    }

    // 连接断开中
    fun onDisconnecting(code: Int, reason: String)
    {
    }

    // 已断开连接
    fun onDisconnected(code: Int, reason: String)
    {
    }

    // 连接失败
    fun onConnectionFailed(t: Throwable)
    {
    }

    // 正在重连
    fun onReconnecting(attempt: Int)
    {
    }
}